//  Copyright (c) Microsoft Corporation.  All Rights Reserved.

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.IdentityModel.Selectors;

namespace EAI.SAML
{
    public class EAISamlProxyRestriction : EAISamlCondition
    {
        int count = 0;
        readonly ImmutableCollection<Uri> audiences = new ImmutableCollection<Uri>();

        bool isReadOnly = false;

        public EAISamlProxyRestriction()
        {
        }

        public int Count
        {
            get { return this.count; }
            set
            {
                if (this.isReadOnly)
                    throw new InvalidOperationException("Object is Read-Only");

                this.count = value;
            }
        }

        public IList<Uri> Audiences
        {
            get { return this.audiences; }
        }

        public override void MakeReadOnly()
        {
            if (!this.isReadOnly)
            {
                this.audiences.MakeReadOnly();
                this.isReadOnly = true;
            }
        }

        public override void ReadXml(XmlReader reader, EAISamlSerializer serializer, SecurityTokenSerializer keyInfoSerializer, SecurityTokenResolver outOfBandTokenResolver)
        {
            if (reader == null)
                throw new ArgumentNullException("reader");

            reader.ReadStartElement(EAISamlConstants.ProxyRestricton, EAISamlConstants.Namespace);
            reader.MoveToContent();

            string attributeValue = reader.GetAttribute(EAISamlConstants.CountAttribute);
            if (!String.IsNullOrEmpty(attributeValue))
                this.count = Convert.ToInt32(attributeValue);

            if (reader.IsEmptyElement)
            {
                reader.Read();
                return;
            }

            if (reader.IsStartElement())
            {
                while (reader.IsStartElement(EAISamlConstants.Audience, EAISamlConstants.Namespace))
                {
                    string val = reader.ReadString();
                    if (String.IsNullOrEmpty(val))
                        throw new SecurityTokenException("<saml:Audience> element cannot specify a null or empty string for audience.");
                    this.audiences.Add(new Uri(val));
                    reader.MoveToContent();
                    reader.ReadEndElement();
                }
            }

            reader.MoveToContent();
            reader.ReadEndElement();
        }

        public override void WriteXml(XmlWriter writer, SecurityTokenSerializer serializer)
        {
            if (writer == null)
                throw new ArgumentNullException("writer");

            writer.WriteStartElement(EAISamlConstants.ProxyRestricton, EAISamlConstants.Namespace);

            if (this.count > 0)
                writer.WriteAttributeString(EAISamlConstants.CountAttribute, count.ToString());

            for (int i = 0; i < this.audiences.Count; ++i)
                writer.WriteElementString(EAISamlConstants.Audience, EAISamlConstants.Namespace, this.audiences[i].ToString());

            writer.WriteEndElement();
        }
    }
}
